home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / Assemblers / 68kasm / opparse.c < prev    next >
C/C++ Source or Header  |  1995-07-26  |  9KB  |  358 lines

  1. /******************************************************************************
  2.  * $Id: opparse.c,v 1.1 1994/08/30 00:04:50 bmott Exp $
  3.  ******************************************************************************
  4.  *
  5.  *        OPPARSE.C
  6.  *        Operand Parser for 68000 Assembler
  7.  *
  8.  *    Function: opParse()
  9.  *        Parses an operand of the 68000 assembly language
  10.  *        instruction and attempts to recognize its addressing
  11.  *        mode. The p argument points to the string to be
  12.  *        evaluated, and the function returns a pointer to the
  13.  *        first character beyond the end of the operand.
  14.  *        The function returns a description of the operands that
  15.  *        it parses in an opDescriptor structure. The fields of
  16.  *        the operand descriptor are filled in as appropriate for
  17.  *        the mode of the operand that was found:
  18.  *
  19.  *         mode      returns the address mode (symbolic values
  20.  *               defined in ASM.H)
  21.  *         reg       returns the address or data register number 
  22.  *         data      returns the displacement or address or
  23.  *               immediate value
  24.  *         backRef   TRUE if data is the value of an expression
  25.  *               that contains only constants and backwards
  26.  *               references; FALSE otherwise.
  27.  *         index     returns the index register
  28.  *               (0-7 = D0-D7, 8-15 = A0-A7)
  29.  *         size      returns the size to be used for the index
  30.  *               register
  31.  *
  32.  *        The argument errorPtr is used to return an error code
  33.  *        via the standard mechanism. 
  34.  *
  35.  *     Usage:    char *opParse(p, d, errorPtr)
  36.  *        char *p;
  37.  *        opDescriptor *d;
  38.  *        int *errorPtr;
  39.  *
  40.  *      Author: Paul McKee
  41.  *        ECE492    North Carolina State University
  42.  *
  43.  *        Date: 10/10/86
  44.  *
  45.  *    Revision: 10/26/87
  46.  *        Altered the immediate mode case to correctly flag
  47.  *        constructs such as "#$1000(A5)" as syntax errors. 
  48.  *
  49.  *   Copyright 1990-1991 North Carolina State University. All Rights Reserved.
  50.  *
  51.  *
  52.  ******************************************************************************
  53.  * $Log: opparse.c,v $
  54.  * Revision 1.1  1994/08/30  00:04:50  bmott
  55.  * Initial revision
  56.  *
  57.  *****************************************************************************/
  58.  
  59.  
  60. #include <stdio.h>
  61. #include <ctype.h>
  62. #include "asm.h"
  63.  
  64.  
  65. extern char pass2;
  66. extern unsigned char absLongFlag;
  67.  
  68.  
  69. #define isTerm(c)   (isspace(c) || (c == ',') || c == '\0')
  70. #define isRegNum(c) ((c >= '0') && (c <= '7'))
  71.  
  72. char *opParse(p, d, errorPtr)
  73. char *p;
  74. opDescriptor *d;
  75. int *errorPtr;
  76. {
  77. char *eval();
  78.  
  79.     /* Check for immediate mode */
  80.     if (p[0] == '#') {
  81.         p = eval(++p, &(d->data), &(d->backRef), errorPtr);
  82.         /* If expression evaluates OK, then return */
  83.         if (*errorPtr < SEVERE) {
  84.             if (isTerm(*p)) {
  85.                 d->mode = Immediate;
  86.                 return p;
  87.                 }
  88.             else {
  89.                 NEWERROR(*errorPtr, SYNTAX);
  90.                 return NULL;
  91.                 }
  92.             }
  93.         else
  94.             return NULL;
  95.         }
  96.     /* Check for address or data register direct */
  97.     if (isRegNum(p[1]) && isTerm(p[2])) {
  98.         if (p[0] == 'D') {
  99.             d->mode = DnDirect;
  100.             d->reg = p[1] - '0';
  101.             return (p + 2);
  102.             }
  103.         else if (p[0] == 'A') {
  104.             d->mode = AnDirect;
  105.             d->reg = p[1] - '0';
  106.             return (p + 2);
  107.             }
  108.         }
  109.     /* Check for Stack Pointer (i.e., A7) direct */
  110.     if (p[0] == 'S' && p[1] == 'P' && isTerm(p[2])) {
  111.         d->mode = AnDirect;
  112.         d->reg = 7;
  113.         return (p + 2);
  114.         }
  115.     /* Check for address register indirect */
  116.     if (p[0] == '(' && 
  117.         ((p[1] == 'A' && isRegNum(p[2])) || (p[1] == 'S' && p[2] == 'P'))) {
  118.         if (p[1] == 'S')
  119.             d->reg = 7;
  120.         else 
  121.             d->reg = p[2] - '0';
  122.         if (p[3] == ')') {
  123.             /* Check for plain address register indirect */
  124.             if (isTerm(p[4])) {
  125.                 d->mode = AnInd;
  126.                 return p+4;
  127.                 }
  128.             /* Check for postincrement */
  129.             else if (p[4] == '+') {
  130.                 d->mode = AnIndPost;
  131.                 return p+5;
  132.                 }
  133.             }
  134.         /* Check for address register indirect with index */
  135.         else if (p[3] == ',' && (p[4] == 'A' || p[4] == 'D')
  136.              && isRegNum(p[5])) {
  137.             d->mode = AnIndIndex;
  138.             /* Displacement is zero */
  139.             d->data = 0;
  140.             d->backRef = TRUE;
  141.             d->index = p[5] - '0';
  142.             if (p[4] == 'A')
  143.                 d->index += 8;
  144.             if (p[6] == '.')
  145.                 /* Determine size of index register */
  146.                 if (p[7] == 'W') {
  147.                     d->size = WORD;
  148.                     return p+9;
  149.                     }
  150.                 else if (p[7] == 'L') {
  151.                     d->size = LONG;
  152.                     return p+9;
  153.                     }
  154.                 else {
  155.                     NEWERROR(*errorPtr, SYNTAX);
  156.                     return NULL;
  157.                     }
  158.             else if (p[6] == ')') {
  159.                 /* Default index register size is Word */
  160.                 d->size = WORD;
  161.                 return p+7;
  162.                 }
  163.             else {
  164.                 NEWERROR(*errorPtr, SYNTAX);
  165.                 return NULL;
  166.                 }
  167.             }
  168.         }
  169.     /* Check for address register indirect with predecrement */
  170.     if (p[0] == '-' && p[1] == '(' && p[4] == ')' &&
  171.         ((p[2] == 'A' && isRegNum(p[3])) || (p[2] == 'S' && p[3] == 'P'))) {
  172.         if (p[2] == 'S')
  173.             d->reg = 7;
  174.         else 
  175.             d->reg = p[3] - '0';
  176.         d->mode = AnIndPre;
  177.         return p+5;
  178.         }
  179.     /* Check for PC relative */
  180.     if (p[0] == '(' && p[1] == 'P' && p[2] == 'C') {
  181.         /* Displacement is zero */
  182.         d->data = 0;
  183.         d->backRef = TRUE;
  184.         /* Check for plain PC relative */
  185.         if (p[3] == ')') {
  186.             d->mode = PCDisp;
  187.             return p+4;
  188.             }
  189.         /* Check for PC relative with index */
  190.         else if (p[3] == ',' && (p[4] == 'A' || p[4] == 'D')
  191.              && isRegNum(p[5])) {
  192.             d->mode = PCIndex;
  193.             d->index = p[5] - '0';
  194.             if (p[4] == 'A')
  195.                 d->index += 8;
  196.             if (p[6] == '.')
  197.                 /* Determine size of index register */
  198.                 if (p[7] == 'W') {
  199.                     d->size = WORD;
  200.                     return p+9;
  201.                     }
  202.                 else if (p[7] == 'L') {
  203.                     d->size = LONG;
  204.                     return p+9;
  205.                     }
  206.                 else {
  207.                     NEWERROR(*errorPtr, SYNTAX);
  208.                     return NULL;
  209.                     }
  210.             else if (p[6] == ')') {
  211.                 /* Default size of index register is Word */
  212.                 d->size = WORD;
  213.                 return p+7;
  214.                 }
  215.             else {
  216.                 NEWERROR(*errorPtr, SYNTAX);
  217.                 return NULL;
  218.                 }
  219.             }
  220.         }
  221.  
  222.     /* Check for Status Register direct */
  223.     if (p[0] == 'S' && p[1] == 'R' && isTerm(p[2])) {
  224.         d->mode = SRDirect;
  225.         return p+2;
  226.         }    
  227.     /* Check for Condition Code Register direct */
  228.     if (p[0] == 'C' && p[1] == 'C' && p[2] == 'R' && isTerm(p[3])) {
  229.         d->mode = CCRDirect;
  230.         return p+3;
  231.         }
  232.     /* Check for User Stack Pointer direct */
  233.     if (p[0] == 'U' && p[1] == 'S' && p[2] == 'P' && isTerm(p[3])) {
  234.         d->mode = USPDirect;
  235.         return p+3;
  236.         }    
  237.     /* Check for Source Function Code register direct (68010) */
  238.     if (p[0] == 'S' && p[1] == 'F' && p[2] == 'C' && isTerm(p[3])) {
  239.         d->mode = SFCDirect;
  240.         return p+3;
  241.         }    
  242.     /* Check for Destination Function Code register direct (68010) */
  243.     if (p[0] == 'D' && p[1] == 'F' && p[2] == 'C' && isTerm(p[3])) {
  244.         d->mode = DFCDirect;
  245.         return p+3;
  246.         }    
  247.     /* Check for Vector Base Register direct (68010) */
  248.     if (p[0] == 'V' && p[1] == 'B' && p[2] == 'R' && isTerm(p[3])) {
  249.         d->mode = VBRDirect;
  250.         return p+3;
  251.         }    
  252.  
  253.     /* All other addressing modes start with a constant expression */
  254.     p = eval(p, &(d->data), &(d->backRef), errorPtr);
  255.     if (*errorPtr < SEVERE) {
  256.         /* Check for absolute */
  257.         if (isTerm(p[0])) {
  258.             /* Determine size of absolute address (must be long if
  259.                the symbol isn't defined or if the value is too big */
  260.             if (!d->backRef || d->data > 32767 || d->data < -32768)
  261.                 d->mode = AbsLong;
  262.             else if ( absLongFlag == TRUE )
  263.                 d->mode = AbsLong;
  264.             else
  265.                 d->mode = AbsShort;
  266.             return p;
  267.             }
  268.         /* Check for address register indirect with displacement */
  269.         if (p[0] == '(' && 
  270.             ((p[1] == 'A' && isRegNum(p[2])) || (p[1] == 'S' && p[2] == 'P'))) {
  271.             if (p[1] == 'S')
  272.                 d->reg = 7;
  273.             else 
  274.                 d->reg = p[2] - '0';
  275.             /* Check for plain address register indirect with displacement */
  276.             if (p[3] == ')') {
  277.                 d->mode = AnIndDisp;
  278.                 return p+4;
  279.                 }
  280.             /* Check for address register indirect with index */
  281.             else if (p[3] == ',' && (p[4] == 'A' || p[4] == 'D')
  282.                  && isRegNum(p[5])) {
  283.                 d->mode = AnIndIndex;
  284.                 d->index = p[5] - '0';
  285.                 if (p[4] == 'A')
  286.                     d->index += 8;
  287.                 if (p[6] == '.')
  288.                     /* Determine size of index register */
  289.                     if (p[7] == 'W') {
  290.                         d->size = WORD;
  291.                         return p+9;
  292.                         }
  293.                     else if (p[7] == 'L') {
  294.                         d->size = LONG;
  295.                         return p+9;
  296.                         }
  297.                     else {
  298.                         NEWERROR(*errorPtr, SYNTAX);
  299.                         return NULL;
  300.                         }
  301.                 else if (p[6] == ')') {
  302.                     /* Default size of index register is Word */
  303.                     d->size = WORD;
  304.                     return p+7;
  305.                     }
  306.                 else {
  307.                     NEWERROR(*errorPtr, SYNTAX);
  308.                     return NULL;
  309.                     }
  310.                 }
  311.             }
  312.         
  313.         /* Check for PC relative */
  314.         if (p[0] == '(' && p[1] == 'P' && p[2] == 'C') {
  315.             /* Check for plain PC relative */
  316.             if (p[3] == ')') {
  317.                 d->mode = PCDisp;
  318.                 return p+4;
  319.                 }
  320.             /* Check for PC relative with index */
  321.             else if (p[3] == ',' && (p[4] == 'A' || p[4] == 'D')
  322.                  && isRegNum(p[5])) {
  323.                 d->mode = PCIndex;
  324.                 d->index = p[5] - '0';
  325.                 if (p[4] == 'A')
  326.                     d->index += 8;
  327.                 if (p[6] == '.')
  328.                     /* Determine size of index register */
  329.                     if (p[7] == 'W') {
  330.                         d->size = WORD;
  331.                         return p+9;
  332.                         }
  333.                     else if (p[7] == 'L') {
  334.                         d->size = LONG;
  335.                         return p+9;
  336.                         }
  337.                     else {
  338.                         NEWERROR(*errorPtr, SYNTAX);
  339.                         return NULL;
  340.                         }
  341.                 else if (p[6] == ')') {
  342.                     /* Default size of index register is Word */
  343.                     d->size = WORD;
  344.                     return p+7;
  345.                     }
  346.                 else {
  347.                     NEWERROR(*errorPtr, SYNTAX);
  348.                     return NULL;
  349.                     }
  350.                 }
  351.             }
  352.         }
  353.  
  354.     /* If the operand doesn't match any pattern, return an error status */
  355.     NEWERROR(*errorPtr, SYNTAX);
  356.     return NULL;
  357. }
  358.